package com.pni.game.cards.components;

import com.pni.game.cards.deck.StandardCardDeckFactory;

/**
 * This data structure represents a table, it contains the functionality
 * necessary to seat players and get players.
 * 
 * @author Phil, Neil
 * 
 */
public class Table {

	private int numberOfSeats;
	private int numberOfPlayers;

	// This array represents the seated players, the index into the array is
	// their seat
	// number. If the seat is empty the position contains a null value
	private Player[] players;

	public Table(int numberOfSeats) {
		this.numberOfSeats = numberOfSeats;
		this.numberOfPlayers = 0;

		players = new Player[numberOfSeats];
		for (int i = 0; i < players.length; i++) {
			players[i] = null;
		}
	}

	/**
	 * Return true is there is no empty seats remaining
	 * 
	 * @return
	 */
	public boolean isTableFull() {
		if (numberOfPlayers < numberOfSeats) {
			return false;
		}
		return true;
	}

	/**
	 * Return the number of seats at the table
	 * 
	 * @return
	 */
	public int getTableSize() {
		return numberOfSeats;
	}

	/**
	 * Return the number of players sitting at the table
	 * 
	 * @return
	 */
	public int getNumberOfPlayers() {
		return numberOfPlayers;
	}

	/**
	 * If a player is at the specified seat change the seat to empty
	 * 
	 * @param seat
	 */
	public void removePlayer(int seat) {
		if (!isSeatEmpty(seat)) {
			this.numberOfPlayers--;
			this.players[seat] = null;
		}
	}

	/**
	 * Check if there is a player sitting at the specified seat
	 * 
	 * @param seat
	 * @return
	 */
	public boolean isSeatEmpty(int seat) {
		boolean isEmpty = true;
		if (seat < 0 || seat >= this.getTableSize()) {
			throw new IllegalArgumentException("Cannot check if seat " + seat
					+ " is empty as it doesn't exist");
		}
		if (players[seat] != null) {
			isEmpty = false;
		}
		return isEmpty;
	}

	public Player[] getPlayers() {
		return players;
	}

	/**
	 * Return the player at the specified seat
	 * 
	 * @param seat
	 * @return
	 */
	public Player getPlayer(int seat) {
		if (seat < 0 || seat >= this.getTableSize()) {
			throw new IllegalArgumentException(
					"Cannot retrieve a player at seat " + seat + " , there is "
							+ this.getTableSize() + " seats");
		}
		return this.players[seat];
	}

	/**
	 * Put a player in a seat, return true is the player was successfully placed
	 * 
	 * @param player
	 */
	public boolean seatPlayer(Player player, int seat) {
		if (isTableFull()) { // check if table is full
			return false;
		}
		if (seat < 0 || seat >= this.numberOfSeats) { // ensure valid seat number
			return false;
		}
		if (players[seat] != null) { // check if a player is already at the selected seat
			return false;
		}
		players[seat] = player;
		players[seat].setSeatNumber(seat);
		this.numberOfPlayers++;
		return true;
	}

	/**
	 * Return an array an integers representing the empty seat numbers
	 * 
	 * @return
	 */
	public int[] getEmptySeats() {
		// Iterate over the player array checking for empty seats
		int[] emptySeats = new int[numberOfSeats - numberOfPlayers];
		int tempIndex = 0;
		for (int i = 0; i < players.length; i++) {
			if (players[i] == null) {
				emptySeats[tempIndex++] = i;
			}
		}
		return emptySeats;
	}

	/**
	 * Return an array an integers representing the seats that are taken
	 * 
	 * @return
	 */
	public int[] getTakenSeats() {
		// Iterate over the player array checking for empty seats
		int[] emptySeats = new int[numberOfSeats - numberOfPlayers];
		int tempIndex = 0;
		for (int i = 0; i < players.length; i++) {
			if (players[i] != null) {
				emptySeats[tempIndex++] = i;
			}
		}
		return emptySeats;
	}

}
